(function () {
  class initSlids {
    constructor({ selector, initWidth, initHeight, width }) {
      //轮播图最小宽度和最大宽度
      this.minWidth = width.min;
      this.maxWidth = width.max;

      // 轮播图初始宽高
      this.initWidth = initWidth;
      this.initHeight = initHeight;

      this.slideshow = selector; //轮播图主体
      this.slideBtns = selector.find('.slide-btn-wrap a'); // 切换图片按钮集合
      this.selBtns = selector.find('.slide-sel-btn a'); //选择图片按钮集合
      this.liArray = selector.find('.slide-img-wrap li'); // 包裹图片的li集合

      this.autoSizeFun(); //根据窗口大小来调整元素大小，来达到响应式的效果
      this.liWidth = this.liArray.width();

      this.slideing = false; //判断是否在滑动，每次只能执行一次滑动效果
      this.timer; //自动轮播时钟
      this.init();
    }
    init () {
      let self = this;
      this.slideBtns.on('click', function () {
        self.slideConvert(this);
      });
      this.selBtns.on('click', function () {
        self.selConvert(this);
      });

      this.autoSlide();

      this.autoSize();
    }

    // 处理跳转至请求的函数，根据 btn的class值求出参数并调用 slide函数
    // 初始值：拿到 class='on'的图片的index值,
    // 移动后的index： 点击上一张就 初始值-1 ，下一张则 +1
    slideConvert (btn) {
      btn = btn || this.slideBtns[1]; //做自动轮播调用的兼容处理，如果没有传入btn值，默认选择向右切换按钮
      var curIndex = this.slideshow.find('.slide-img-wrap .on').attr('index');
      curIndex = parseInt(curIndex);
      if (btn.className == 'next') {
        var nextIndex = (curIndex + 1 + 8) % 8;
      } else {
        var nextIndex = (curIndex - 1 + 8) % 8;
      }
      this.slide(curIndex, nextIndex);
    }

    // 处理选择图片按钮的函数
    // 初始值：拿到 class='on'的图片的index值,
    // 移动后的index:被点击的按钮的index值
    selConvert (btn) {
      var curIndex = this.slideshow.find('.slide-img-wrap .on').attr('index');
      var nextIndex = btn.getAttribute('index');
      nextIndex = parseInt(nextIndex);
      curIndex = parseInt(curIndex);
      this.slide(curIndex, nextIndex);
    }

    // 移动幻灯片位置
    // 1.拿到当前幻灯片的left值 ：curLeft
    // 2.算出移动后的幻灯片的left值 ：nextLeft
    // 3.然后调用过度动画slideAnimate 将参数传进去
    // 4.根据移动后的index值，把当前图片的 选择图片按钮，包裹图片的li设置为显示状态
    slide (curIndex, nextIndex) {
      if (this.slideing) return; //判断函数如果在运行状态，则退出函数
      this.slideing = true; //执行滑动操作前，把 slideing设为运行状态

      var imgList = this.slideshow.find('.slide-img-wrap').get(0);

      var curLeft = curIndex * (this.liWidth * -1);
      var nextLeft = nextIndex * (this.liWidth * -1);
      this.slideAnimate(curLeft, nextLeft, imgList, 600);

      if (nextIndex == this.liArray.length - 1) {
        nextIndex = 1;
      } else if (nextIndex == 0) {
        nextIndex = this.liArray.length - 2;
      }

      // 把li标签和span标签的选中的那个标签的class的 on设置一下。
      this.liArray[curIndex].className = '';
      this.liArray[nextIndex].className = 'on';

      // slide-sel-btn 下面的a标签 重新设置on
      this.selBtns[curIndex].className = '';
      this.selBtns[nextIndex].className = 'on';
    }

    // 移动动画效果 计算出每毫秒的滑动距离，然后根据已经过去的时间设置left值
    /**
     *  @description 产生过度动画效果
     *  @param {number} curLeft 初始位置
     *  @param {number} nextLeft 移动后的位置
     *  @param {HTMLElemnet} element 要进行动画的元素
     *  @param {number} nextLeft 动画的过度时间
     */
    slideAnimate (curLeft, nextLeft, element, decoration) {
      var distance = nextLeft - curLeft; // 总的滑动的距离
      var distanceMS = distance / decoration; //每毫秒需要滑动的距离
      var startTime = Date.now();
      var timer = setInterval(() => {
        this.autoSlide(); //在运行滑动动画时，重置自动轮播timer
        var pasTime = Date.now() - startTime;
        element.style.left = curLeft + pasTime * distanceMS + 'px';
        if (pasTime >= decoration) {
          this.resizeInit();
          this.slideing = false; //执行完滑动操作后，把 slideing设为静止状态
          if (
            element.style.left ==
            this.liWidth * (this.liArray.length - 1) * -1
          ) {
            element.style.left = this.liWidth * -1 + 'px';
          } else if (element.style.left == '0px') {
            element.style.left =
              this.liWidth * (this.liArray.length - 2) * -1 + 'px';
          }
          clearInterval(timer);
        }
      }, 1000 / 60);
    }

    //自动轮播
    autoSlide () {
      // 先去掉时钟。
      if (this.timer) {
        clearInterval(this.timer);
        this.timer = null;
      }

      // 实现自动滚动效果。
      this.timer = setInterval(() => {
        this.slideConvert();
      }, 3000);
    }

    // 调整屏幕大小后自动调整 slide-img-wrap的left
    resizeInit () {
      var curIndex = this.slideshow.find('.slide-img-wrap .on').attr('index');
      curIndex = parseInt(curIndex);
      this.slideshow
        .find('.slide-img-wrap')
        .css('left', curIndex * -1 * this.liWidth + 'px');
    }

    // 防抖调用元素大小函数
    autoSize () {
      var timer = null;
      var self = this;
      $(window).resize(function () {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(self.autoSizeFun.bind(self), 300);
      });
    }

    //调整元素大小函数 ，来达到响应式的效果
    autoSizeFun () {
      var docEle = document.documentElement;
      var width = docEle.clientWidth;
      width = width < this.minWidth ? this.minWidth : width;
      width = width > this.maxWidth ? this.maxWidth : width;

      if (!width) return;
      var scale = width / this.maxWidth; // 缩小的比例

      // 根据页面大小设置元素宽高
      // 设置 slideshow宽高  当页面小于980px 时让高度自适应
      // 设置 slide-img-wrap 宽度，高度根据子元素自适应
      // 设置 slide-img-wrap li宽度 高度根据子元素自适应
      // 设置 slide-img-wrap li img 宽高 ，解决 .slide-img-wrap 根据子元素获取高度错误的兼容问题
      // 设置 slide-btn-wrap 的 top值
      // this.initWidth 轮播图显示区域初始宽度
      // this.initHeight 轮播图显示区域初始高度

      var slideWidth = this.initWidth * scale;
      this.slideshow
        .find('.slide-img-wrap')
        .css('width', slideWidth * 8 + 'px'); //设置 .slide-img-wrap宽度
      this.slideshow
        .find('.slide-img-wrap li a img,.slide-img-wrap li ,.header-mark')
        .css('width', slideWidth + 'px')
        .css('opacity', 1);

      var slideHeight = Math.ceil(this.initHeight * scale);
      this.slideshow
        .find('.slide-img-wrap li a img')
        .css('height', slideHeight + 'px'); //处理 .slide-img-wrap 根据子元素获取高度的兼容
      this.slideshow
        .find('.slide-btn-wrap ')
        .css('top', slideHeight / 2 + 'px');

      this.userDiyFun(width, slideWidth, slideHeight, scale);

      this.liWidth = slideWidth;
      this.resizeInit();
    }

    // 自定义函数
    // 接收参数 width：当前浏览器窗口的宽度  scale:原始大小需要缩小的比例
    // 接收参数 slideWidth：响应式幻灯片的宽度   slideHeight：响应式幻灯片的高度
    userDiyFun (width, slideWidth, slideHeight, scale) {
      $('.header-mark')
        .css('width', slideWidth + 'px')
        .css('opacity', 1);
      // 设置 slide-sel-btn  的 top值
      this.slideshow.find('.slide-sel-btn').css('top', slideHeight + 'px');

      if (width > 980) {
        //给slideshow设置幻灯片加上 选择图片按钮的高度
        this.slideshow.css('height', 767 * scale + 36 + 'px');

        //设置文字描述区域
        this.slideshow
          .find('.slide-img-wrap li .text-caption')
          .css({
            left: 100 * scale + 'px',
            top: 190 * scale + 'px'
          })
          .css('opacity', 1);
      } else {
        this.slideshow
          .find('.slide-img-wrap li .text-caption')
          .attr('style', 'color')
          .css('opacity', 1);

        //给 slideshow 设为自动获取高度
        this.slideshow.css('height', 'auto');
      }
    }
  }

  $(function () {
    new initSlids({
      selector: $('#slideshow'),
      initWidth: 1680,
      initHeight: 757,
      width: {
        min: 320,
        max: 1680
      }
    });
  });
})();
